﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MyMainSite.Repositories;
using MyMainSite.Factories;

namespace MyMainSite.Models
{
    public class BaseModel
    {
        #region Properties

        public string CurrentController
        {
            get { return _currentController; }
            set { _currentController = value; }
        }
        private string _currentController = String.Empty;

        public string CurrentProject
        {
            get { return _currentProject; }
            set { _currentProject = value; }
        }
        private string _currentProject = String.Empty;

        public DateTime CurrentBlogDate
        {
            get { return _currentBlogDate; }
            set { _currentBlogDate = value; }
        }
        private DateTime _currentBlogDate = DateTime.MinValue;

        public Blog CurrentBlog
        {
            get { return _currentBlog; }
            set { _currentBlog = value; }
        }
        private Blog _currentBlog = new Blog();

        public int CurrentYear
        {
            get { return _currentYear; }
            set { _currentYear = value; }
        }
        private int _currentYear = DateTime.Now.Year;

        public int CurrentMonth
        {
            get { return _currentMonth; }
            set { _currentMonth = value; }
        }
        private int _currentMonth = -1;

        public string CurrentTitle
        {
            get { return _currentTitle; }
            set { _currentTitle = value; }
        }
        private string _currentTitle = String.Empty;

        public string CurrentFriendlyUrl
        {
            get { return _currentFriendlyUrl; }
            set { _currentFriendlyUrl = value; }
        }
        private string _currentFriendlyUrl = String.Empty;

        public readonly int MinimumBlogYear = 2011;

        public List<Project> Projects { get; set; }

        public List<KeyValuePair<string, string>> BreadCrumb
        {
            get { return _breadCrumb; }
            set { _breadCrumb = value; }
        }
        private List<KeyValuePair<string, string>> _breadCrumb = new List<KeyValuePair<string, string>>();

        public List<BlogEntry> BlogEntries
        {
            get { return _blogEntries; }
            set { _blogEntries = value; }
        }
        private List<BlogEntry> _blogEntries = new List<BlogEntry>();

        public List<Blog> Blogs { get; set; }

        public Dictionary<int, int> ProjectBlogEntryCount
        {
            get { return _projectBlogEntryCount; }
            set { _projectBlogEntryCount = value; }
        }
        private Dictionary<int, int> _projectBlogEntryCount = new Dictionary<int, int>();

        public Dictionary<string, int> DateBlogEntryCount
        {
            get { return _dateBlogEntryCount; }
            set { _dateBlogEntryCount = value; }
        }
        private Dictionary<string, int> _dateBlogEntryCount = new Dictionary<string, int>();

        #endregion

        #region Public Methods

        public BaseModel()
        {
            this.Setup();
        }

        public BaseModel(int year, int month)
        {
            this.CurrentYear = year;
            this.CurrentMonth = month;

            this.Setup();
        }

        #endregion

        #region Private Methods

        private void Setup()
        {
            RichardsSiteEntities dc = new RichardsSiteEntities();
            var repo = RepositoryFactory<ProjectRepositoryImplemented>.GetRepository();

            this.Projects = (from p in dc.Projects
                             orderby p.Name descending
                             select p).ToList();

            this.Blogs = (from b in dc.Blogs
                          orderby b.Name ascending
                          select b).ToList();

            foreach (var p in this.Projects)
            {
                int count = repo.GetBlogCountByProjectId(p.ProjectId);

                this.ProjectBlogEntryCount.Add(p.ProjectId, count);

                this.SetupProjectBlogCountForDates(p.ProjectId, repo);
            }
        }

        private void SetupProjectBlogCountForDates(int projectId, IProjectRepository repo)
        {
            var startDate = new DateTime(this.MinimumBlogYear, 1, 1);
            var loopDate = DateTime.Now;

            while (loopDate > startDate)
            {
                if (loopDate.Year != this.CurrentYear)
                {
                    this.SaveBlogEntryDate(projectId, loopDate, repo);

                    loopDate = loopDate.AddMonths(-loopDate.Month); // bring to Jan of the previous year
                }
                else
                {
                    while (loopDate.Year == this.CurrentYear)
                    {
                        this.SaveBlogEntryDate(projectId, loopDate, repo);

                        loopDate = loopDate.AddMonths(-1);
                        if (loopDate <= startDate)
                            break;
                    }
                }
            }
        }

        private void SaveBlogEntryDate(int projectId, DateTime date, IProjectRepository repo)
        {
            int count = repo.GetBlogCountByProjectIdAndDate(projectId, date);

            string key = date.ToShortDateString();

            if (!this.DateBlogEntryCount.ContainsKey(key))
                this.DateBlogEntryCount.Add(key, 0);

            this.DateBlogEntryCount[key] += count;
        }

        #endregion
    }
}